package com.xdjd.mobile.business.service;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.gitee.easyopen.exception.ApiException;
import com.xdjd.mobile.business.entity.param.alipay.AlipayCreateParam;
import com.xdjd.mobile.business.entity.result.alipay.AlipayTradeAppPayVo;
import com.xdjd.mobile.business.util.MoneyUtils;
import com.xdjd.mobile.system.config.AlipayConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

@Service
public class AliPayService implements EnvironmentAware {
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private AlipayConfig alipayConfig;

    private volatile AlipayClient client;

    private String springProfilesPctive;

    @Override
    public void setEnvironment(Environment environment) {
        springProfilesPctive = environment.getProperty("spring.profiles.active");
    }

    public AlipayTradeAppPayVo createAliPayReq(AlipayCreateParam param) {
        try {
            AlipayTradeAppPayRequest request = this.buildAlipayTradeAppPayRequest(param, alipayConfig.getNotify_url());
            AlipayClient client = getPayClient();
            // 调用SDK生成表单
            AlipayTradeAppPayResponse response = client.sdkExecute(request);
            if (response.isSuccess()) {
                // 获取到getBody直接給前端。用这个东西去调起支付宝
                AlipayTradeAppPayVo vo = new AlipayTradeAppPayVo();
                vo.setBody(response.getBody());
                return vo;
            } else {
                logger.error("调用SDK生成表单失败,{}", JSON.toJSONString(response));
                throw new ApiException(response.getSubMsg());
            }
        } catch (ApiException e) {
            logger.error("支付失败", e);
            throw new ApiException(e.getMessage(), "-1");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new ApiException("支付失败", "-1");
        }
    }

    private AlipayTradeAppPayRequest buildAlipayTradeAppPayRequest(AlipayCreateParam param, String notifyUrl) {
        // SDK 公共请求类，包含公共请求参数，以及封装了签名与验签，开发者无需关注签名与验签
        // 调用RSA签名方式
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        // 封装请求支付信息
        AlipayTradeAppPayModel model = this.buildAlipayTradeAppPayModel(param);
        try {
            // 用户自定义参数
            model.setPassbackParams(URLEncoder.encode(JSON.toJSONString(param), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 如果是测试环境,金额都是1分
        if (springProfilesPctive != null && "dev,test".contains(springProfilesPctive) && !"0".equals(model.getTotalAmount())) {
            model.setTotalAmount("0.01");
        }
        logger.info("支付model:{}", JSON.toJSONString(model));
        request.setBizModel(model);
        // 设置异步通知地址
        logger.info(param.getPayName() + "回调地址：" + notifyUrl);
        request.setNotifyUrl(notifyUrl);
        return request;
    }

    private AlipayTradeAppPayModel buildAlipayTradeAppPayModel(AlipayCreateParam param) {
        byte payType = param.getPayType();
        String orderNo = param.getOutTradeNo();
        // 封装请求支付信息
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        // 1:实物交易
        model.setGoodsType("1");
        try {
            // 用户自定义参数
            model.setPassbackParams(URLEncoder.encode(JSON.toJSONString(param), "UTF-8"));
            if (1 == payType) {
                model.setOutTradeNo(orderNo);
                model.setSubject("用户充值");
                model.setTotalAmount(MoneyUtils.formatMoney(param.getPayAmount()));
                model.setBody("用户充值");
            } else if (2 == payType) {
                model.setOutTradeNo(orderNo);
                model.setSubject("用户支付激励金");
                model.setTotalAmount(MoneyUtils.formatMoney(param.getPayAmount()));
                model.setBody("用户支付激励金");
            } else if (3 == payType) {
                model.setOutTradeNo(orderNo);
                model.setSubject("用户追加激励金");
                model.setTotalAmount(MoneyUtils.formatMoney(param.getPayAmount()));
                model.setBody("用户追加激励金");
            } else {
                throw new ApiException("支付类型错误");
            }
        } catch (UnsupportedEncodingException e) {
            logger.error("用户自定义参数urlEncode失败：" + e);
            throw new ApiException("处理支付参数失败");
        }
        return model;
    }

    private AlipayClient getPayClient() {
        if (client == null) {
            synchronized (AliPayService.class) {
                if (client == null) {
                    client = new DefaultAlipayClient(alipayConfig.getGateway_url(), alipayConfig.getAppid(),
                            alipayConfig.getRsa_private_key(), alipayConfig.getFormat(), alipayConfig.getCharset(),
                            alipayConfig.getAlipay_public_key(), alipayConfig.getSigntype());
                }
            }
        }
        return client;
    }

}
